﻿// Copyright (c) 2008 Paul Schaeflein
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in 
// the Software without restriction, including without limitation the rights to use, 
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
// Software, and to permit persons to whom the Software is furnished to do so, subject 
// to the following conditions:

// The above copyright notice and this permission notice shall be included in all 
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Collections;

namespace Schaeflein.Community.StsAdmExtensions
{
  class ImageUploadLocation : ExtensionCommandBase
  {
    public override string Help()
    {
      StringBuilder sb = new StringBuilder();

      //sb.AppendLine("stsadm.exe -o SetImageUploadLocation");
      sb.AppendLine("  -webapp <web application url> ");
      //sb.AppendLine("          (-library <library url> | -remove)");
      sb.AppendLine("          -library <library url>");
      sb.AppendLine();
      sb.AppendLine("Sets the storage location for the Image Upload Web Part. The");
      sb.AppendLine("location is set in the web.config file");
      sb.AppendLine();
      sb.AppendLine("Use the -webapp parameter to specify the url of the web ");
      sb.AppendLine("application which is to be modified.");
      sb.AppendLine();
      sb.AppendLine("Use the -library parameter to specify the url of the library");
      sb.AppendLine("that will hold the images. The library can be in any web application.");
      //sb.AppendLine();
      //sb.AppendLine("Use the -remove parameter to remove the setting from the ");
      //sb.AppendLine("web.config file.");
      sb.AppendLine();

      return sb.ToString();
    }

    public override STSADMResultCodes Run(System.Collections.Specialized.StringDictionary keyValues, out string output)
    {
      string webapp_parm = keyValues["webapp"];
      string library_parm = keyValues["library"];
      bool remove_parm = keyValues.ContainsKey("remove");

      Uri webAppUrl = null;
      Uri libraryUrl = null;

      if (String.IsNullOrEmpty(webapp_parm))
      {
        output = "The -webapp parameter was not specified.";
        return STSADMResultCodes.SyntaxError;
      }
      else
      {
        if (!Uri.TryCreate(webapp_parm, UriKind.Absolute, out webAppUrl))
        {
          output = "The -webapp parameter is not a valid URL.";
          return STSADMResultCodes.SyntaxError;
        }
      }

      // library is not allowed with remove
      if (remove_parm)
      { 
        if (!String.IsNullOrEmpty(library_parm))
        {
          output = "The -library parameter cannot be specified with -remove.";
          return STSADMResultCodes.SyntaxError;
        }
      }
      else
      {
        if (String.IsNullOrEmpty(library_parm))
        {
          output = "The -library parameter was not specified.";
          return STSADMResultCodes.SyntaxError;
        }
        else
        {
          if (!Uri.TryCreate(library_parm, UriKind.Absolute, out libraryUrl))
          {
            output = "The -library parameter is not a valid URL.";
            return STSADMResultCodes.SyntaxError;
          }
        }
      }

      // verify the webapp exists
      SPWebApplication webapp = SPWebApplication.Lookup(webAppUrl);
      if (webapp == null)
      {
        output = "The web application specified does not exist.";
        return STSADMResultCodes.SyntaxError;
      }

      // verify the library exists
      if (!String.IsNullOrEmpty(library_parm))
      {
        using (SPSite site = new SPSite(library_parm))
        {
          using (SPWeb web = site.OpenWeb())
          {
            SPFolder docFolder = web.GetFolder(library_parm);
            if (docFolder == null)
            {
              output = "The library does not exist.";
              return STSADMResultCodes.SyntaxError;
            }
          }
        }
      }


      // we're good to go...
      output = " ";
      try
      {
        RaiseStatus(Environment.NewLine + "Setting location ...");
        ModifyWebConfig(webapp, library_parm, remove_parm);
      }
      catch (Exception e)
      {
        output += e.ToString();
        return STSADMResultCodes.GeneralError;
      }

      output += Environment.NewLine + "Operation completed sucessfully";
      return STSADMResultCodes.Success;
    }

    private void RemoveWebConfig(SPWebApplication webapp)
    {
      throw new Exception("The method or operation is not implemented.");
    }

    public bool ModifyWebConfig(SPWebApplication webApp, string libraryUrl, bool remove)
    {
      bool appSettingsPresent = false;
      bool imageUploadPresent = false;
      bool updateNecessary = false;
      SPWebConfigModification wmToDelete = null;

      foreach (SPWebConfigModification wm in webApp.WebConfigModifications)
      {
        if (wm.Name == "appSettings" && wm.Path == "configuration")
        {
          appSettingsPresent = true;
        }
        if (wm.Name == "add[@key='Schaeflein.Community.WebParts.ImageUpload']" && 
            wm.Path == @"configuration/appSettings" )
        {
          imageUploadPresent = true;

          if (remove)
          {
            ////wmToDelete = wm;
            ////updateNecessary = true;
          }
          else
          {
            string value = String.Format("<add key=\"{0}\" value=\"{1}\" />", "Schaeflein.Community.WebParts.ImageUpload", libraryUrl);
            if (wm.Value != value)
            {
              wm.Value = value;
              updateNecessary = true;
            }
          }
        }
      }

      try
      {
        if (!appSettingsPresent)
        {
          // <appSettings />
          SPWebConfigModification wm1 = new SPWebConfigModification();
          wm1.Name = "appSettings";
          wm1.Path = @"configuration";
          wm1.Owner = "WSS";
          wm1.Sequence = 1;
          wm1.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
          wm1.Value = "<appSettings/>";
          webApp.WebConfigModifications.Add(wm1);
          updateNecessary = true;
        }

        if (!imageUploadPresent)
        {
          // <add key="Schaeflein.Community.WebParts.ImageUpload" value="..."  />
          SPWebConfigModification wm2 = new SPWebConfigModification();
          wm2.Name = "add[@key='Schaeflein.Community.WebParts.ImageUpload']";
          wm2.Path = @"configuration/appSettings";
          wm2.Owner = "Schaeflein.Community.WebParts";
          wm2.Sequence = 2;
          wm2.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
          wm2.Value = String.Format("<add key=\"{0}\" value=\"{1}\" />", "Schaeflein.Community.WebParts.ImageUpload", libraryUrl);
          webApp.WebConfigModifications.Add(wm2);
          updateNecessary = true;
        }

        if (updateNecessary)
        {
          // delete is necessary
          ////if (wmToDelete != null)
          ////{
          ////  webApp.WebConfigModifications.Remove(wmToDelete);
          ////}
          // now apply the changes
          webApp.Update();
          SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
        }
        return true;

      }
      catch 
      {
        throw;
      }
    }
  }
}